home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AppsToGo / pbClock / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  10.1 KB  |  376 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        Menu.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1990-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19.  
  20.  
  21. /*****************************************************************************/
  22.  
  23.  
  24.  
  25. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  26. #include "App.defs.h"        /* Get various application definitions.            */
  27. #include "App.protos.h"        /* Get the prototypes for application.            */
  28.  
  29. #ifndef __DESK__
  30. #include <Desk.h>
  31. #endif
  32.  
  33. #ifndef __ERRORS__
  34. #include <Errors.h>
  35. #endif
  36.  
  37. #ifndef __MEMORY__
  38. #include <Memory.h>
  39. #endif
  40.  
  41. #ifndef __MENUS__
  42. #include <Menus.h>
  43. #endif
  44.  
  45. #ifndef __TOOLUTILS__
  46. #include <ToolUtils.h>
  47. #endif
  48.  
  49. #ifndef __UTILITIES__
  50. #include "Utilities.h"
  51. #endif
  52.  
  53.  
  54.  
  55. /*****************************************************************************/
  56.  
  57.  
  58.  
  59. extern Boolean    gQuitApplication;
  60. extern Boolean    gHasAppleEvents;
  61. extern OSType    gAppWindowType;
  62.  
  63. extern Boolean    gLowOnMem;
  64. extern short    gDialogErr;
  65.  
  66.  
  67.  
  68. /*****************************************************************************/
  69. /*****************************************************************************/
  70.  
  71. #ifdef applec
  72. #pragma segment Menu
  73. #endif
  74.  
  75. /*****************************************************************************/
  76. /*****************************************************************************/
  77.  
  78.  
  79.  
  80. /* •• Called by DTS.Lib..framework. •• */
  81.  
  82. /* Adjust the menu items.  We allow the DTS.Lib framework to do most of the work
  83. ** for us.  It will walk the menubar, and for each menu in the menubar, it will
  84. ** disable all of the menu items and then call the application at either
  85. ** AdjustMenuItems() (for document and palette windows, or for the no-window case),
  86. ** or DialogAdjustMenuItems() (for modal dialogs).  The application's job is to then
  87. ** turn on menu items that should be enabled to match the current application state.
  88. ** The initial Wannabe code for AdjustMenuItems() calls DoAdjustFileMenu() for the
  89. ** file menu, and DoAdjustEditMenu() for the edit menu.  Any other menus that may
  90. ** be added to Wannabe have all menu items enabled.  This allows menus to be added
  91. ** to the running version of Wannabe and allows them to actually do something.
  92. ** If the top-most window is a dialog, then all menus are disabled except for the
  93. ** edit menu.  Various items in the edit menu are enabled, depending on if there
  94. ** is an active TextEdit control, and what is in the clipboard. */
  95.  
  96. void    DoAdjustMenus(void)
  97. {
  98.     if (DoAdjustMBARMenus(FrontWindow(), rMenuBar))
  99.         DrawMenuBar();
  100. }
  101.  
  102.  
  103.  
  104. /*****************************************************************************/
  105.  
  106.  
  107.  
  108. /* This is called when an item is chosen from the menu bar (after calling
  109. ** MenuSelect or MenuKey).  It performs the right operation for each command.
  110. ** It is good to have both the result of MenuSelect and MenuKey go to one
  111. ** routine like this to keep everything organized. */
  112.  
  113. Boolean    DoMenuCommand(short menuID, short menuItem)
  114. {
  115.     short        undoDepth, numUndos, saveMode, daRefNum;
  116.     Str255        daName;
  117.     FileRecHndl    frHndl;
  118.     WindowPtr    window;
  119.     TEHandle    te;
  120.     OSErr        err;
  121.     Boolean        handled;
  122.     RGBColor    oldc, newc;
  123.  
  124.     handled = true;
  125.  
  126.     window = FrontWindow();
  127.     if (window)
  128.         frHndl = (FileRecHndl)GetWRefCon(window);
  129.             /* frHndl is valid only if it is one of our windows. */
  130.  
  131.     switch (menuID) {
  132.  
  133.         case mApple:
  134.             switch (menuItem) {
  135.                 case kStdAbout:        /* Bring up alert for About. */
  136.                     NewDocumentWindow(nil, 'ABOT', false);
  137.                     break;
  138.                 default:            /* All non-About items in this menu are DAs. */
  139.                     GetMenuItemText(GetMenuHandle(mApple), menuItem, daName);
  140.                     daRefNum = OpenDeskAcc(daName);
  141.                     break;
  142.             }
  143.             break;
  144.  
  145.         case mFile:
  146.             switch (menuItem) {
  147.                 case kStdNew:
  148.                     gDialogErr = NewDocumentWindow(&frHndl, gAppWindowType, true);
  149.                     if (gDialogErr)
  150.                         NewDocumentWindow(nil, 'ERR#', false);
  151.                     break;
  152.                 case kStdOpen:
  153.                     err = OpenDocumentWindow(&frHndl, nil, fsRdWrPerm);
  154.                     if ((err) && (err != userCanceledErr)) {
  155.                         gDialogErr = err;
  156.                         NewDocumentWindow(nil, 'ERR#', false);
  157.                     }
  158.                     break;
  159.                 case kStdClose:
  160.                     if (IsAppWindow(window)) {
  161.                         window = FrontWindowOfType(kwIsDocument, true);
  162.                         if (window)
  163.                             DisposeOneWindow(window, kClose);
  164.                     }
  165.                     else
  166.                         DisposeOneWindow(window, kClose);        /* Dispose of DA window. */
  167.                     break;
  168.                 case kStdSave:
  169.                 case kStdSaveAs:
  170.                     saveMode = (menuItem == kStdSave) ? kSave : kSaveAs;
  171.                     if ((*frHndl)->fileState.refNum == kInvalRefNum)
  172.                         saveMode = kSaveAs;
  173.                     err = SaveDocument(frHndl, window, saveMode);
  174.                     if ((err) && (err != userCanceledErr)) {
  175.                         gDialogErr = err;
  176.                         NewDocumentWindow(nil, 'ERR#', false);
  177.                     }
  178.                     break;
  179.                 case kStdPageSetup:
  180.                     DoSetCursor(&qd.arrow);
  181.                     PresentStyleDialog(frHndl);
  182.                     break;
  183.                 case kStdPrint:
  184.                     DoSetCursor(&qd.arrow);
  185.                     err = noErr;
  186.                     if (!(*frHndl)->d.doc.fhInfo.printRecValid)
  187.                         err = PresentStyleDialog(frHndl);
  188.                     if (!err) {
  189.                         err = PrintDocument(frHndl, true, true);
  190.                         PrintDocument(nil, false, false);
  191.                     }
  192.                     if ((err) && (err != userCanceledErr)) {
  193.                         gDialogErr = err;
  194.                         NewDocumentWindow(nil, 'ERR#', false);
  195.                     }
  196.                     break;
  197.                 case kStdQuit:
  198.                     gQuitApplication = DisposeAllWindows();
  199.                     break;
  200.                 default:
  201.                     handled = false;
  202.                     break;
  203.             }
  204.             break;
  205.  
  206.         case mEdit:            /* Call SystemEdit for DA editing & MultiFinder. */
  207. #if VH_VERSION
  208.             if (menuItem == kStdViewHier) {
  209.                 handled = false;
  210.                 break;
  211.             }
  212. #endif
  213.             if (IsAppWindow(window)) {
  214.                 switch (menuItem) {
  215.                     case kStdUndo:
  216.                     case kStdRedo:
  217.                     case kStdCut:
  218.                     case kStdCopy:
  219.                     case kStdPaste:
  220.                     case kStdClear:
  221.                         switch ((*frHndl)->fileState.sfType) {
  222.                                 /* This is written with the assumption that document types
  223.                                 ** that demand specific code will be added.  The below “if”
  224.                                 ** illustrates how to handle the edit menu for windows that
  225.                                 ** have an active TextEdit control.  The “else” shows a typical
  226.                                 ** undo/redo scenario for applications that are using the
  227.                                 ** hierarchical document package.  The clipboard features
  228.                                 ** are of course document-dependent, so a sample hasn't been
  229.                                 ** implemented here.  For a sample, see DTS.Draw. */
  230.                             default:
  231.                                 te = CTEFindActive(window);
  232.                                 if (te) {
  233.                                     if (gQDVersion) {
  234.                                         GetBackColor(&oldc);
  235.                                         newc.red = newc.green = newc.blue = 0xFFFF;
  236.                                         RGBBackColor(&newc);
  237.                                             /* The window color is non-white, but
  238.                                             ** the control area containing TEControls
  239.                                             ** is white.  Therefore we have to set
  240.                                             ** the backColor to white before doing
  241.                                             ** TEControl operations, or else we
  242.                                             ** will get some weird results. */
  243.                                     }
  244.                                     if ((*te)->viewRect.left < -8192)
  245.                                         BeginFrame(window);
  246.                                     else
  247.                                         BeginContent(window);
  248.                                     if (menuItem == kStdUndo)
  249.                                         CTEUndo();
  250.                                     else
  251.                                         CTEClipboard(menuItem - kStdCut + 2);
  252.                                     EndContent(window);
  253.                                     if (gQDVersion)
  254.                                         RGBBackColor(&oldc);
  255.                                 }
  256.                                 else {
  257.                                     if (menuItem <= kStdRedo) {
  258.                                         if (!UnmapMItem(mEdit, kStdUndo)) {
  259.                                             GetUndoInfo(frHndl, &undoDepth, &numUndos);
  260.                                             DoUndoTask((*frHndl)->d.doc.root, 1 - undoDepth, true);
  261.                                         }
  262.                                         else DoUndoTask((*frHndl)->d.doc.root, menuItem - kStdUndo, true);
  263.                                     }
  264.                                     else {
  265.                                         /* Handle rest of edit menu here. */
  266.                                     }
  267.                                 }
  268.                                 break;
  269.                         }
  270.                         break;
  271.                 }
  272.             }
  273.             else SystemEdit(menuItem - 1);
  274.             break;
  275.  
  276.         default:
  277.             handled = false;
  278.             break;
  279.  
  280.     }
  281.  
  282.     return(handled);
  283. }
  284.  
  285.  
  286.  
  287. /*****************************************************************************/
  288.  
  289.  
  290.  
  291. Boolean    DoAdjustFileMenu(WindowPtr window)
  292. {
  293.     MenuHandle    menu;
  294.     FileRecHndl    frHndl;
  295.     short        enableItem;
  296.  
  297.     menu = GetMenuHandle(mFile);
  298.     EnableItem(menu, UnmapMItem(mFile, kStdQuit));            /* Gotta be able to quit. */
  299.  
  300.     if (IsDAWindow(window)) {
  301.         EnableItem(menu, UnmapMItem(mFile, kStdClose));        /* Let DAs do a close from the menu. */
  302.         return(false);
  303.     }
  304.  
  305.     if (!gLowOnMem) {
  306.         EnableItem(menu, UnmapMItem(mFile, kStdNew));
  307.         EnableItem(menu, UnmapMItem(mFile, kStdOpen));
  308.     }
  309.  
  310.     window = FrontWindowOfType(kwIsDocument, true);
  311.     if (window) {
  312.         EnableItem(menu, UnmapMItem(mFile, kStdClose));
  313.         frHndl = (FileRecHndl)GetWRefCon(window);
  314.         if ((*frHndl)->fileState.sfType == kDocFileType) {
  315.             enableItem = GetWindowDirty(window);
  316.             if ((*frHndl)->fileState.refNum == kInvalRefNum)
  317.                 enableItem = true;
  318.             if (enableItem)
  319.                 EnableItem(menu, UnmapMItem(mFile, kStdSave));
  320.             EnableItem(menu, UnmapMItem(mFile, kStdSaveAs));
  321.         }
  322.         EnableItem(menu, UnmapMItem(mFile, kStdPageSetup));
  323.         EnableItem(menu, UnmapMItem(mFile, kStdPrint));
  324.     }
  325.  
  326.     return(false);
  327. }
  328.  
  329.  
  330.  
  331. /*****************************************************************************/
  332.  
  333.  
  334.  
  335. Boolean    DoAdjustEditMenu(WindowPtr window)
  336. {
  337.     MenuHandle        menu;
  338.     Boolean            menuEnabled;
  339.     FileRecHndl        frHndl;
  340.  
  341.     menu = GetMenuHandle(mEdit);
  342.  
  343.     if (IsDAWindow(window)) {
  344.         EnableItem(menu, UnmapMItem(mEdit, kStdUndo));
  345.         EnableItem(menu, UnmapMItem(mEdit, kStdCut));
  346.         EnableItem(menu, UnmapMItem(mEdit, kStdCopy));
  347.         EnableItem(menu, UnmapMItem(mEdit, kStdPaste));
  348.         EnableItem(menu, UnmapMItem(mEdit, kStdClear));
  349.         return(false);
  350.     }
  351.  
  352.     if (IsAppWindow(window)) {
  353.         frHndl = (FileRecHndl)GetWRefCon(window);
  354.         switch ((*frHndl)->fileState.sfType) {
  355. #if VH_VERSION
  356.             case kViewHierFileType:
  357.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  358.                                                  UnmapMItem(mEdit, kStdCut));
  359.                 break;
  360. #endif
  361.             default:
  362. #if VH_VERSION
  363.                 EnableItem(menu, UnmapMItem(mEdit, kStdViewHier));
  364. #endif
  365.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  366.                                                  UnmapMItem(mEdit, kStdCut));
  367.                 break;
  368.         }
  369.     }
  370.  
  371.     return(false);
  372. }
  373.  
  374.  
  375.  
  376.